home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 172_01 / yylex.c < prev   
Text File  |  1980-01-01  |  5KB  |  186 lines

  1. /*
  2.   HEADER:              CUG  nnn.nn;
  3.   TITLE:               LEX - A Lexical Analyser Generator
  4.   VERSION:             1.1 for IBM-PC
  5.   DATE:                Jan 30, 1985
  6.   DESCRIPTION:         A Lexical Analyser Generator. From UNIX
  7.   KEYWORDS:            Lexical Analyser Generator YACC C PREP
  8.   SYSTEM:              IBM-PC and Compatiables
  9.   FILENAME:            YYLEX.C
  10.   WARNINGS:            This program is not for the casual user. It will
  11.                        be useful primarily to expert developers.
  12.   CRC:                 N/A
  13.   SEE-ALSO:            YACC and PREP
  14.   AUTHORS:             Charles H. Forsyth
  15.                        Scott Guthery 11100 leafwood lane Austin, TX 78750
  16.                        Andrew M. Ward, Jr.  Houston, Texas (Modifications)
  17.   COMPILERS:           LATTICE C
  18.   REFERENCES:          UNIX Systems Manuals -- Lex Manual on distribution disks
  19. */
  20. /*
  21.  * Copyright (c) 1978 Charles H. Forsyth
  22.  *
  23.  * Modified 02-Dec-80 Bob Denny -- Conditionalize debug code for reduced size
  24.  * Modified 29-May-81 Bob Denny -- Clean up overlay stuff for RSX.
  25.  * More     19-Mar-82 Bob Denny -- New C library & compiler
  26.  * More     03-May-82 Bob Denny -- Final touches, remove unreferenced autos
  27.  * More     29-Aug-82 Bob Denny -- Clean up -d printouts
  28.  * More     29-Aug-82 Bob Denny -- Reformat for readability and comment
  29.  *                                 while learning about LEX.
  30.  * More     20-Nov-83 Scott Guthery -- Adapt for IBM PC & DeSmet C
  31.  *
  32.  * Modified 22-Jun-86 Andrew Ward -- Modified code to compile under Lattice C
  33.  *                                 version 3.0h.  Corrected several errors
  34.  *                                 from the assumption that pointers and
  35.  *                                 integers are the same size.     
  36.  *                                 New debug code for LATTICE C using assert
  37.  *                                 to test for wild pointers.
  38.  */
  39.  
  40. /*
  41.  * yylex for lex tables
  42.  */
  43. #include "lex.h"
  44.  
  45. #define YYSTYPE int
  46. #define ERROR   256     /* yacc's value */
  47. extern YYSTYPE yylval;
  48. tst__b(c, tab)
  49. int    c;
  50. char            tab[];
  51. {
  52.     return(tab[(c >> 3) & 037] & (1 << (c & 07)) );
  53. }
  54.  
  55. struct  lextab  *_tabp = NULL;
  56.  
  57. extern char     *llsave[];      /* Right-context buffer                 */
  58. char    llbuf[100];             /* work buffer                          */
  59. char    *llp1   = &llbuf[0];    /* pointer to next avail. in token      */
  60. char    *llp2   = &llbuf[0];    /* pointer to end of lookahead          */
  61. char    *llend  = &llbuf[0];    /* pointer to end of token              */
  62. char    *llebuf = &llbuf[sizeof( llbuf)];
  63. int     lleof;
  64. int     yylval  = 0; /* This is not compatible */
  65. int     yyline  = 0;
  66.  
  67. int yylex()
  68. {
  69.     int c, st;
  70.     int final, l, llk, i;
  71.  
  72.     struct lextab *lp;
  73.     char *cp;
  74.  
  75.     /*
  76.      * Call llstin() to default lexin to stdin
  77.      * and assign _tabp to "real" table.
  78.      */
  79.     llstin();                       /* Initialize yylex() variables */
  80.  
  81. loop:
  82.     llk = 0;
  83.     if(llset())
  84.         return(0);              /* Prevent EOF loop     */
  85.     st = 0;
  86.     final = -1;
  87.     lp = _tabp;
  88.  
  89.     do {
  90.         if (lp->lllook && (l = lp->lllook[st])) {
  91.             for (c=0; c<NBPW; c++)
  92.                 if (l&(1<<c))
  93.                     llsave[c] = llp1;
  94.             llk++;
  95.         }
  96.         if ((i = lp->llfinal[st]) != -1) {
  97.             final = i;
  98.             llend = llp1;
  99.         }
  100.         if ((c = llinp()) < 0)
  101.             break;
  102.         if ((cp = lp->llbrk) && llk==0 && tst__b(c, cp)) {
  103.             llp1--;
  104.             break;
  105.         }
  106.     } while ((st = (*lp->llmove)(lp, c, st)) != -1);
  107.  
  108.  
  109.     if(llp2 < llp1)
  110.         llp2 = llp1;
  111.     if(final == -1) {
  112.         llend = llp1;
  113.         if (st == 0 && c < 0)
  114.             return(0);
  115.         if ((cp = lp->llill) && tst__b(c, cp)) {
  116.             lexerror("Illegal character: %c (%03o)", c, c);
  117.             goto loop;
  118.         }
  119.         return(ERROR);
  120.     }
  121.     if(c = (final >> 11) & 037)
  122.         llend = llsave[c-1];
  123.     if((c = (*lp->llactr)(final&03777)) >= 0)
  124.         return(c);
  125.     goto loop;
  126. }
  127.  
  128. llinp()
  129. {
  130.  
  131.     int c;
  132.     struct lextab *lp;
  133.     char *cp;
  134.  
  135.     lp = _tabp;
  136.     cp = lp->llign;                         /* Ignore class         */
  137.     for(;;) {
  138.         /*
  139.          * Get the next character from the save buffer (if possible)
  140.          * If the save buffer's empty, then return EOF or the next
  141.          * input character.  Ignore the character if it's in the
  142.          * ignore class.
  143.          */
  144.         c = (llp1 < llp2) ? *llp1 & CMASK : (lleof) ? EOF : lexgetc();
  145.         if(c >= 0) {                   /* Got a character?     */
  146.             if(cp && tst__b(c, cp))
  147.                 continue;       /* Ignore it            */
  148.             if(llp1 >= llebuf) {   /* No, is there room?   */
  149.                 lexerror("Token buffer overflow");
  150.                 exit(1);
  151.             }
  152.             *llp1++ = c;            /* Store in token buff  */
  153.         } else
  154.             lleof = 1;              /* Set EOF signal       */
  155.         return(c);
  156.     }
  157. }
  158.  
  159. llset()
  160. /*
  161.  * Return TRUE if EOF and nothing was moved in the look-ahead buffer
  162.  */
  163. {
  164.     char *lp1, *lp2;
  165.  
  166.     for(lp1 = llbuf, lp2 = llend; lp2 < llp2;)
  167.         *lp1++ = *lp2++;
  168.     llend = llp1 = llbuf;
  169.     llp2 = lp1;
  170.     return(lleof && lp1 == llbuf);
  171. }
  172.  
  173. /*
  174.  * Re-initialize yylex() so that it can be re-used on
  175.  * another file.
  176.  */
  177. llinit()
  178.    {
  179.    llp1 = llp2 = llend = llbuf;
  180.    llebuf = llbuf + sizeof(llbuf);
  181.    lleof = yylval = yyline = 0;
  182.    }
  183.  
  184.  
  185.  
  186.